//
//  ProcessHUD.swift
//  FearfulNotification
//
//  Created by 筱鹏 on 2018/3/23.
//  Copyright © 2018年 筱鹏. All rights reserved.
//

import UIKit

fileprivate class ProcessHUDView: UIView {
    
    let backView:UIView!
    let indicatorView: UIActivityIndicatorView!
    let indicatorLabel: UILabel!
    
    override init(frame: CGRect) {
        backView = UIView()
        indicatorView = UIActivityIndicatorView(style: .whiteLarge)
        indicatorLabel = UILabel()
        super.init(frame: frame)
        configSubview()
    }
    
    required init?(coder aDecoder: NSCoder) {
        backView = UIView ()
        indicatorView = UIActivityIndicatorView(style: .whiteLarge)
        indicatorLabel = UILabel()
        super.init(coder: aDecoder)
        configSubview()
    }
    
    lazy var maskBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.addTarget(self, action: .maskBtnSel, for: .touchUpInside)
        return btn
    }()
    
    var maskAllGesture: Bool {
        set {
            if newValue {
                self.maskBtn.removeFromSuperview()
            } else {
                self.insertSubview(self.maskBtn, at: 0)
                self.maskBtn.frame = self.bounds
                self.maskBtn.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            }
        }
        get {
            return self.maskBtn.superview != nil
        }
    }
    
    private func configSubview() {
        self.addSubview(self.backView)
        self.backView.addSubview(self.indicatorView)
        self.backView.addSubview(self.indicatorLabel)
        
        self.backView.frame = CGRect(x: 0, y: 0, width: ScreenWidth*0.5, height: ScreenWidth*0.5)
        
        indicatorView.frame = CGRect(x: 0, y: 0, width: backView.frame.width, height: backView.frame.height - 50)
        indicatorLabel.frame = CGRect(x: 0, y: indicatorView.frame.maxY + 10, width: backView.frame.width, height: 30)
        
        indicatorView.autoresizingMask = [.flexibleWidth]
        indicatorLabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        backView.backgroundColor = Theme.color.indicatorBackground
        backView.layer.cornerRadius = 20
        backView.layer.masksToBounds = true
        
        indicatorLabel.numberOfLines = 0
        indicatorLabel.textColor = Theme.color.indicatorForeground
        indicatorLabel.textAlignment = .center
        indicatorLabel.font = Theme.font.indicatorForeground
        
        indicatorView.color = Theme.color.indicatorForeground
    }
    
    private func showAnimatePrepare(showText: String?) {
        backView.alpha = 0.0
        let centerPoint = ViewManager.window.convert(ViewManager.window.center, to: self.superview)
        self.backView.center = centerPoint
        
        indicatorView.startAnimating()
        if let text = showText {
            indicatorLabel.text = text
            let size = indicatorLabel.sizeThatFits(CGSize(width: ScreenWidth * 0.7, height: ScreenHeight * 0.5))
            if size.width > backView.frame.width {
                backView.frame.size.width = size.width
                backView.frame.size.height += (size.height - 30)
                let centerPoint = ViewManager.window.convert(ViewManager.window.center, to: self.superview)
                backView.center = centerPoint
            }
        } else {
            indicatorView.frame = backView.bounds
        }
    }
    
    private func showEndAnimatePrepare() {
        backView.alpha = 1.0
    }
    
    private func hiddenEndAnimatePrepare() {
        backView.alpha = 0.0
        indicatorLabel.text = nil;
        indicatorView.stopAnimating()
    }
}

private extension Selector {
    static let maskBtnSel = #selector(ProcessHUDView.maskBtnAction(sender:))
}

fileprivate extension ProcessHUDView {
    
    @objc func maskBtnAction(sender: UIButton) {
        hidden()
    }
    
    func autoDismiss(_ time: TimeInterval) {
        if time > 0 {
            self.perform(.maskBtnSel, with: self, afterDelay: time)
        } else {
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: .maskBtnSel, object: nil)
        }
    }
    
    func show(onView: UIView, text: String?) {
        self.frame = onView.bounds;
        onView.addSubview(self)
        self.showAnimatePrepare(showText: text)
        UIView.animate(withDuration: 0.2, animations: {
            self.showEndAnimatePrepare()
        }) { (success) in
            if success {
                
            }
        }
    }
    
    func hidden() {
        UIView.animate(withDuration: 0.2, animations: {
            self.hiddenEndAnimatePrepare()
        }) { (success) in
            if success {
                self.removeFromSuperview()
            }
        }
    }
    

}

struct ProcessHUD {
    fileprivate static var view: ProcessHUDView? {
        willSet {
            if let _ = newValue {
                guard let oldView = view else { return }
                oldView.hidden()
            }
        }
    }
    
    enum LoadingType {
        case loading
        case hint
        case value
    }
    
    static func show(_ type: LoadingType, text: String?) {
        let hud = self.showLoading(onView: ViewManager.window, text: text)
        switch type {
        case .loading:
            hud.maskAllGesture = false
            break
        case .hint:
            hud.maskAllGesture = false
            hud.autoDismiss(3)
            break
        default:
            break
        }
    }
    
    private static func showLoading(onView: UIView, text: String?) -> ProcessHUDView {
        let hud = ProcessHUDView()
        view = hud
        hud.show(onView: onView, text: text)
        return hud
    }
    
    static func showLoading(onView: UIView) {
        let hud = ProcessHUDView()
        view = hud
        hud.show(onView: onView, text: nil)
    }
    
    static func showLoading() {
        let hud = ProcessHUDView()
        view = hud
        hud.show(onView: ViewManager.window, text: nil)
    }
    
    static func showLoading(text: String) {
        let hud = ProcessHUDView()
        view = hud
        hud.show(onView: ViewManager.window, text: text)
    }
    
    static func hideLoading() {
        guard let hud = view else { return }
        hud.hidden()
        view = nil
    }
    

}
